# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from decimal import Decimal
from plugins.paid.ailpay import AlipayService
from plugins.paid.wxpay import WxpayService
from common.utils.tools import ToolsUtil
from common.enums.pay import PayEnum
from common.models.public import RefundRecordModel
from common.models.market import RechargeOrderModel
from common.models.market import SubscribeOrderModel


class RefundLogic:

    @classmethod
    async def refund(cls, scene: str, order_id: int, refund_amount: Decimal, admin_id: int = 0):
        # 查询订单
        order = None
        if scene == "recharge":
            order = await RechargeOrderModel.filter(id=order_id, is_delete=0).first()
        elif scene == "subscribe":
            order = await SubscribeOrderModel.filter(id=order_id, is_delete=0).first()

        # 验证订单
        if order is None:
            raise Exception("找不到相关订单")

        # 验证金额
        if refund_amount <= 0:
            raise Exception("退款金额不可为0")

        # 验证实付
        if refund_amount > order.paid_amount:
            raise Exception("退款金额不能超出实付金额")

        # 创建退款记录
        record = await RefundRecordModel.filter(order_type=scene, order_id=order_id).first()
        refund_sn = await ToolsUtil.make_order_sn(RefundRecordModel, "refund_sn")
        if not record:
            refund_type = "back" if admin_id else "user"
            record = await RefundRecordModel.create(
                admin_id=admin_id,
                user_id=order.user_id,
                order_id=order.id,
                order_type=scene,
                refund_type=refund_type,
                refund_sn=refund_sn,
                order_sn=order.order_sn,
                transaction_id=order.transaction_id,
                total_amount=order.paid_amount,
                refund_amount=refund_amount,
                refund_status=PayEnum.REFUND_ING,
                create_time=int(time.time()),
                update_time=int(time.time())
            )
        else:
            order.refund_status = PayEnum.REFUND_ING
            await order.save()
            await RefundRecordModel.filter(id=record.id).update(
                refund_sn=refund_sn,
                refund_amount=refund_amount,
                refund_status=PayEnum.REFUND_ING,
                update_time=int(time.time())
            )

        # 按支付方式退
        if order.pay_way == PayEnum.WAY_MNP:
            await WxpayService.refund(
                transaction_id=order.transaction_id,
                out_refund_no=record.refund_sn,
                refund_amount=refund_amount,
                total_amount=order.paid_amount
            )
        elif scene == PayEnum.WAY_ALI:
            await AlipayService.refund(
                transaction_id=order.transaction_id,
                out_refund_no=record.refund_sn,
                refund_amount=refund_amount
            )
